using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Web.Profile;
using TestSystem.DAL.TestSystem;

namespace TestSystem.BLL.TestSystem
{
    public class Quiz : BusinessEntity
    {
        #region private fields
        private int _quizID;
        private string _title;
        private string _description;
        private int _subjectID;
        private DateTime _addedDate;
        private string _addedBy;
        private int _passedTimes;
        private int _failedTimes;
        private int _questionsCount;
        private bool _useTimer;
        private int _timePerQuiz;
        private int _scoreToPass;
        private bool _active;
        private bool _deleted;
        private bool _saveUserAnswers;
        private bool _allowReAnswer;
        private int _maxScores;
        private string _levelsPercentage;
        #endregion 

        #region public prop and methods
        public int QuizID
        {
            get { return _quizID; }
            set { _quizID = value; }
        }

        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        public int SubjectID
        {
            get { return _subjectID; }
            set { _subjectID = value; }
        }

        public DateTime AddedDate
        {
            get { return _addedDate; }
            set { _addedDate = value; }
        }

        public string AddedBy
        {
            get { return _addedBy; }
            set { _addedBy = value; }
        }

        public int PassedTimes
        {
            get { return _passedTimes; }
            set { _passedTimes = value; }
        }

        public int FailedTimes
        {
            get { return _failedTimes; }
            set { _failedTimes = value; }
        }

        public int QuestionsCount
        {
            get { return _questionsCount; }
            set { _questionsCount = value; }
        }

        public bool UseTimer
        {
            get { return _useTimer; }
            set { _useTimer = value; }
        }

        public int TimePerQuiz
        {
            get { return _timePerQuiz; }
            set { _timePerQuiz = value; }
        }

        public int ScoreToPass
        {
            get { return _scoreToPass; }
            set { _scoreToPass = value; }
        }

        public bool Active
        {
            get { return _active; }
            set { _active = value; }
        }

        public bool Deleted
        {
            get { return _deleted; }
            set { _deleted = value; }
        }

        public bool SaveUserAnswers
        {
            get { return _saveUserAnswers; }
            set { _saveUserAnswers = value; }
        }

        public bool AllowReAnswer
        {
            get { return _allowReAnswer; }
            set { _allowReAnswer = value; }
        }

        public int MaxScores
        {
            get { return _maxScores; }
            set { _maxScores = value; }
        }

        public string LevelsPercentage
        {
            get { return _levelsPercentage; }
            set { _levelsPercentage = value; }
        }

        private List<Test> _tests = null;
        public List<Test> Tests
        {
            get
            {
                if (_tests == null)
                    _tests = Test.GetByQuizID(this.QuizID);
                return _tests;
            }
        }
        
        private ProfileBase _author = null;
        public ProfileBase Author
        {
            get
            {
                if (_author == null)
                    _author = ProfileBase.Create(this.AddedBy);
                return _author;
            }
        }

        private Subject _subject = null;
        public Subject Subject
        {
            get
            {
                if (_subject == null)
                    _subject = Subject.GetBySubjectID(this.SubjectID);
                return _subject;
            }
        }

        private int _testsCount = 0;
        public int TestsCount
        {
            get
            {
                if (_testsCount != 0)
                    _testsCount = Test.GetCountByQuizID(this.QuizID);
                return _testsCount;
            }
        }

        public int AddTest(string body, int testOrder, int complexity, int testType)
        {
            return Test.Add(this.QuizID, body, testOrder, complexity, testType);
        }

        public void RemoveTests()
        {
            Test.RemoveByQuizID(this.QuizID);
        }

        public override void Update()
        {
            QuizDataAccess.UpdateQuiz(this.QuizID, this.Title, this.Description, this.SubjectID, this.AddedDate,
                                      this.AddedBy, this.PassedTimes, this.FailedTimes, this.QuestionsCount, this.UseTimer, 
                                      this.TimePerQuiz, this.ScoreToPass, this.Active, this.Deleted, this.SaveUserAnswers, 
                                      this.AllowReAnswer, this.MaxScores, this.LevelsPercentage);
        }
                
        protected override void Load(IDataReader rdr)
        {
            QuizID = (int)rdr["QuizID"];
            Title = QuizDataAccess.FromDBValue<string>(rdr["Title"]);
            Description = QuizDataAccess.FromDBValue<string>(rdr["Description"]);
            SubjectID = (int)rdr["SubjectID"];
            AddedDate = (DateTime)rdr["AddedDate"];
            AddedBy = QuizDataAccess.FromDBValue<string>(rdr["AddedBy"]);
            PassedTimes = (int)rdr["PassedTimes"];
            FailedTimes = (int)rdr["FailedTimes"];
            QuestionsCount = (int)rdr["QuestionsCount"];
            UseTimer = (bool)rdr["UseTimer"];
            TimePerQuiz = (int)rdr["TimePerQuiz"];
            ScoreToPass = (int)rdr["ScoreToPass"];
            Active = (bool)rdr["Active"];
            Deleted = (bool) rdr["Deleted"];
            SaveUserAnswers = (bool) rdr["SaveUserAnswers"];
            AllowReAnswer = (bool) rdr["AllowReAnswer"];
            MaxScores = (int) rdr["MaxScores"];
            LevelsPercentage = QuizDataAccess.FromDBValue<string>(rdr["LevelsPercentage"]);

        }
        #endregion

        #region static methods
        public static List<Quiz> GetBySubjectID(int subjectID)
        {
            return LoadList<Quiz>(QuizDataAccess.GetQuizesBySubjectID(subjectID));
        }

        public static List<Quiz> GetBySubjectID(int subjectID, bool selectDeleted, bool selectActive)
        {
            return LoadList<Quiz>(QuizDataAccess.GetQuizesBySubjectID(subjectID, selectDeleted, selectActive));
        }
        
        public static int Add(string title, string description, int subjectID, string addedBy, int questionsCount, bool useTimer, int timePerQuiz, int scoreToPass, bool active, bool saveUserAnswers, int maxScores, string levelsPercentage)
        {
            return QuizDataAccess.InsertQuiz(title, description, subjectID, DateTime.Now, addedBy, 0, 0, questionsCount, useTimer, timePerQuiz, scoreToPass, active, false, saveUserAnswers, true, maxScores, levelsPercentage);
        }

        public static int Add(SqlTransaction tran, string title, string description, int subjectID, string addedBy, int questionsCount, bool useTimer, int timePerQuiz, int scoreToPass, bool active, int maxScores, string levelsPercentage)
        {
            return QuizDataAccess.InsertQuiz(tran, title, description, subjectID, DateTime.Now, addedBy, 0, 0, questionsCount, useTimer, timePerQuiz, scoreToPass, active, false, false, true, maxScores, levelsPercentage);
        }

        public static void RemoveBySubjectID(int subjectID)
        {
            QuizDataAccess.DeleteBySubjectID(subjectID);
        }

        public static int GetCountBySubjectID(int subjectID)
        {
            return QuizDataAccess.GetCountBySubjectID(subjectID);
        }

        public static void Remove(int quizID)
        {
            QuizDataAccess.Delete(quizID);
        }
        
        public static List<Quiz> GetAll()
        {
            return LoadList<Quiz>(QuizDataAccess.GetAll());
        }

        public static List<Quiz> GetAll(bool selectDeleted, bool selectActive)
        {
            return LoadList<Quiz>(QuizDataAccess.GetAll(selectDeleted, selectActive));
        }

        public static Quiz GetByQuizID(int quizID)
        {
            return LoadEntity<Quiz>(QuizDataAccess.GetByQuizID(quizID));
        }

        public static int GetCount()
        {
            return QuizDataAccess.GetCount();
        }
        #endregion
    }
}
